/************************************************************************/
/* Customized and extended version,                                     */
/* Original from James Waples Copyright (c) 2010                        */
/* http://www.jamwaffles.co.uk/index.php?p=downloads&s=cod&a=obl&dc     */
/************************************************************************/

#include "DevilTexture.h"
#include "Game.h"
#include "Renderer.h"

using namespace std;

#ifndef GL_CLAMP_TO_EDGE 
#define GL_CLAMP_TO_EDGE 0x812F 
#endif

#define LOG_CATEGORY "DevilTexture: "

DevilTexture::DevilTexture() {
	if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) {
		Game::log.LogWarn(LOG_CATEGORY "Wrong devil version");
	}
	ilInit();

	this->isLoaded = false;
}

DevilTexture::~DevilTexture() {
	
}

int DevilTexture::Load(const char *fileName, bool anisotropy) {
	ilGenImages(1, &ilTexID);
	ilBindImage(ilTexID);
	success = ilLoadImage(fileName);
	if(success) {
		success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); // Convert every colour component into	unsigned byte. If your texID contains alpha channel you can replace IL_RGB with IL_RGBA
        success = ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
        success = ilEnable(IL_ORIGIN_SET);

		if(!success) {
			Game::log.LogError(LOG_CATEGORY "Could not convert image");
			return 1;
		}
		glGenTextures(1, &texID); // Texture name generation
		glBindTexture(GL_TEXTURE_2D, texID); // Binding of texture name 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // We will use linear interpolation for magnification filter
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // We will use linear interpolation for minifying filter
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		if(Renderer::IsAnisotropySupported() && anisotropy) {
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Renderer::GetMaxAnisotropy());
		}

		glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH),
			ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE,
			ilGetData()); // Texture specification

		width = ilGetInteger(IL_IMAGE_WIDTH);
		height = ilGetInteger(IL_IMAGE_HEIGHT); 
	} else {
		Game::log.LogError(LOG_CATEGORY "OpenGL texture generation failed");
		return 1;
	}
	ilDeleteImages(1, &ilTexID); // Because we have already copied texID data into texture data we can release memory used by texID.
	this->isLoaded = true;
	return 0;
}

void DevilTexture::Use() {
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texID);
}

bool DevilTexture::IsLoaded() {
	return this->isLoaded;
}

int DevilTexture::GetTextureID() {
	if(this->isLoaded) {
		return this->texID;
	} else {
		return -1;
	}
}

int DevilTexture::GetWidth() {
	if(this->isLoaded) {
		return this->width;
	} else {
		return -1;
	}
}

int DevilTexture::GetHeight() {
	if(this->isLoaded) {
		return this->height;
	} else {
		return -1;
	}
}
